#pragma once
#include <string>

#include "Probability.h"
#include "SearchEngine.h"

class Board {
 public:
  void InitMap(char cMap[12][5],
               std::string& cOutMessage);  //双方布局后棋局初始化
  //   char cMap[12][5] 棋盘局面	char *cOutMessage 布局字符序列
  void FreshMap(char cMap[12][5], char* cInMessage,
                std::string& cOutMessage);  //根据裁判反馈刷新棋盘
  // cMap[12][5] 棋盘局面 cInMessage 裁判命令 cOutMessage 发给裁判的命令
  void CallArray(char* cInMessage, int* iFirst, int* iTime, int* iStep,
                 std::string& cOutMessage);  //返回布局
  void CallBestmove(char cMap[12][5], char* cInMessage,
                    std::string& cOutMessage,
                    ChessMove bestmove);  //返回下一步
  void initVector(Vector (*vectors)[5]);  //初始化Vector
  void transformChess(
      char CMap[12][5],
      Vector (*vectors)[5]);  //转化界面传递过来的信息并且更新至顶点数组中
  void transformcMap(char cMap[12][5], char (*CMap)[5], Chance C[25],
                     Probability pb);  //转化棋面
  void CalInfo(char* cInMessage, char* cVer,
               std::string& cOutMessage) {  // 初始化队名
    cOutMessage = "GROUP 2";
  }

 private:
  Probability Bpb;
};

void Board::InitMap(char cMap[12][5], std::string& cOutMessage) {
  int i, j, k;
  for (i = 0; i < 6; i++)  //标记对方棋子
    for (j = 0; j < 5; j++)
      if (Bpb.iscamp(i, j))
        cMap[i][j] = '0';  //行营不能放子，故为0
      else
        cMap[i][j] = 'X';  //对方棋子未知，以X代替
  k = 6;  //回复己方布局消息中，布局数组的偏移量
  for (i = 6; i < 12; i++)  //标记己方棋子
    for (j = 0; j < 5; j++)
      if (Bpb.iscamp(i, j))
        cMap[i][j] = '0';  //行营不能放子
      else
        cMap[i][j] = cOutMessage[k++];  //将cOutMessage中的棋子序列放入棋盘中
}

void Board::FreshMap(char cMap[12][5], char* cInMessage,
                     std::string& cOutMessage) {
  char x1, y1;                 //起点
  char x2, y2;                 //落点
  char result = -1;            //碰子结果
  if (cInMessage[0] == 'G') {  // GO 指令
    if (cInMessage[3] >= 'A' && cInMessage[3] <= 'L') {
      y1 = cInMessage[3] - 'A';      //
      x1 = cInMessage[4] - '0';      //取得起点与落点坐标
      y2 = cInMessage[5] - 'A';      //
      x2 = cInMessage[6] - '0';      //
      result = cInMessage[8] - '0';  //碰子结果
      if (cInMessage[10] >= 'A' && cInMessage[10] <= 'L')
        //对方司令战死后显示军旗位置，若为00表示军旗位置未知
        cMap[(cInMessage[10] - 'A')][cInMessage[11] - '0'] = 'L';
      //修改棋盘，将对方军旗位置写入棋盘
      switch (result) {  //根据不同结果修改棋盘
        case 0:          //对方棋子被己方吃掉
          cMap[y1][x1] =
              '0';  //清空起点位置，由于对方棋子被我方吃掉，所以不更新落点
          break;
        case 1:                         //对方吃掉己方棋子
          cMap[y2][x2] = cMap[y1][x1];  //将对方棋子移动到落点位置
          cMap[y1][x1] = '0';           //并清空起点
          break;
        case 2:                //双方棋子对死
          cMap[y1][x1] = '0';  //清空起点位置
          cMap[y2][x2] = '0';  //清空落点位置
          break;
        case 3:                         //对方移动棋子
          cMap[y2][x2] = cMap[y1][x1];  //将对方棋子移动到落点
          cMap[y1][x1] = '0';           //并清空起点位置
          break;
      }
    }
  }
  if (cInMessage[0] == 'R') {  // RESULT 指令，裁判返回己方行棋结果
    y1 = cOutMessage[9] - 'A';     //计算我方
    x1 = cOutMessage[10] - '0';    //棋子起点与
    y2 = cOutMessage[11] - 'A';    //--落点--
    x2 = cOutMessage[12] - '0';    //--坐标
    result = cInMessage[7] - '0';  //行棋结果
    if (cInMessage[8] == ' ' && cInMessage[9] >= 'A' &&
        cInMessage[9] <= 'L')  //对方司令战死后显示军旗位置
      cMap[(cInMessage[9] - 'A')][cInMessage[10] - '0'] = 'L';
    switch (result) {  //根据不同结果修改棋盘
      case 0:          //己方棋子被对方吃掉
        cMap[y1][x1] = '0';
        break;
      case 1:                         //己方吃掉对方棋子
        cMap[y2][x2] = cMap[y1][x1];  //移动我方棋子到落点坐标
        cMap[y1][x1] = '0';           //清空起点
        break;
      case 2:                //双方棋子对死
        cMap[y1][x1] = '0';  //清空起点
        cMap[y2][x2] = '0';  //清空落点
        break;
      case 3:  //己方移动棋子
        cMap[y2][x2] = cMap[y1][x1];
        cMap[y1][x1] = '0';
        break;
    }
  }
}

void Board::CallArray(char* cInMessage, int* iFirst, int* iTime, int* iStep,
                      std::string& cOutMessage) {
  *iFirst = cInMessage[6] - '0';  //通过减法，将char转化为int，取得是否先行
  if (*iFirst == 0) {             //先手
    // strcpy(cOutMessage,"ARRAY cigdcegkefkfaibgidjhhhjlj");//改过了的飘香一剑
    // 还是有点克双喜 strcpy(cOutMessage,"ARRAY
    // cigcdegkefkfaibgidjhhhjlj");//改过了的飘香一剑   还是有点克双喜
    // cOutMessage="ARRAY cegicdfkkhiebdagijjjghhlf";//改过的双喜临门  攻防有据
    // strcpy(cOutMessage, "ARRAY diahcbgkkfiecfigjhedjljhg");
    // strcpy(cOutMessage,"ARRAY fhbicdieagkcghkedgjfihjlj");//于无声处
    // strcpy(cOutMessage,"ARRAY fiehgciadgbhgiekdcfjkhjlj");//乌龙摆尾
    // 先手有点克制双喜临门 strcpy(cOutMessage,"ARRAY
    // aibheeiggikcdghdkcjffhjlj");//三节阵    防御不错  暂时没测出效果
    // strcpy(cOutMessage,"ARRAY eihigagccffedikkgdjbhhjlj");//雾山重剑
    // strcpy(cOutMessage,"ARRAY ecdiafggkdibkgfejhicjljhh");//改过的布局
    // strcpy(cOutMessage, "ARRAY fgdigdichkkhgihjjejealbfc");
    cOutMessage = "ARRAY diahcbgkkfiecfigjhedjljhg";  // 1
    // cOutMessage = "ARRAY cdhghkecebikifgjaijgjlfhd";三峡布局
    // cOutMessage = "ARRAY hhbiaciefkhkgdgcjeidjljgf";//破釜沉舟
    // // strcpy(cOutMessage, "ARRAY cidfckaggkdhgeiifjbhehjlj");
  } else  //后手
  {
    // strcpy(cOutMessage,"ARRAY cebidkhfgdiakgfcjeigjljhh");
    // strcpy(cOutMessage,"ARRAY cigdcegkefkfaibgidjhhhjlj");//改过了的飘香一剑
    // 还是有点克双喜 strcpy(cOutMessage,"ARRAY
    // cigcdegkefkfaibgidjhhhjlj");//改过了的飘香一剑   还是有点克双喜
    // strcpy(cOutMessage,"ARRAY cegicdfkkhiebdagijjjghhlf");//改过的双喜临门
    // 攻防有据 strcpy(cOutMessage,"ARRAY fhbicdieagkcghkedgjfihjlj");//于无声处
    // strcpy(cOutMessage,"ARRAY fiehgciadgbhgiekdcfjkhjlj");//乌龙摆尾
    // 先手有点克制双喜临门 strcpy(cOutMessage,"ARRAY
    // aibheeiggikcdghdkcjffhjlj");//三节阵    防御不错  暂时没测出效果
    // strcpy(cOutMessage,"ARRAY eihigagccffedikkgdjbhhjlj");//雾山重剑
    // strcpy(cOutMessage, "ARRAY cigdcegkefkfaigbidjhhhjlj");
    // strcpy(cOutMessage, "ARRAY diahcbgkkfiecfigjhedjljhg");1
    // cdhghkecebikifgjaijgjlfhd  三峡后手
    cOutMessage = "ARRAY cibhfeidckgakhgfjgjedljhi";  // 2
  }
}

void Board::CallBestmove(char cMap[12][5], char* cInMessage,
                         std::string& cOutMessage, ChessMove bestmove) {
  cOutMessage = "BESTMOVE A0A0";  //定义回复消息模板，通过下面四句代码形成走法
  cOutMessage[9] = bestmove.fx + 'A';   // fx==fromX
  cOutMessage[10] = bestmove.fy + '0';  // fy==fromY
  cOutMessage[11] = bestmove.tx + 'A';  // tx==toX
  cOutMessage[12] = bestmove.ty + '0';  // ty==toY
}

void Board::initVector(Vector (*vectors)[5]) {
  int i, j;
  for (i = 0; i < 12; i++) {
    for (j = 0; j < 5; j++) {
      vectors[i][j].row = i;  //行坐标
      vectors[i][j].col = j;  //列坐标
      if ((i == 0) || (i == 11)) {
        vectors[i][j].isStuck = 1;
      }
      if (((i == 2) && (j == 1)) || ((i == 2) && (j == 3)) ||
          ((i == 3) && (j == 2)) || ((i == 4) && (j == 1)) ||
          ((i == 4) && (j == 3)) || ((i == 7) && (j == 1)) ||
          ((i == 7) && (j == 3)) || ((i == 8) && (j == 2)) ||
          ((i == 9) && (j == 1)) || ((i == 9) && (j == 3))) {
        vectors[i][j].isSave = 1;  //标志行营
      }
    }
  }
  //标志公路
  for (i = 1; i <= 10; i++) {
    vectors[i][0].isRoad = 1;
    vectors[i][4].isRoad = 1;
  }
  for (j = 1; j <= 3; j++) {
    vectors[1][j].isRoad = 1;
    vectors[5][j].isRoad = 1;
    vectors[6][j].isRoad = 1;
    vectors[10][j].isRoad = 1;
  }
}

void Board::transformChess(char CMap[12][5], Vector (*vectors)[5]) {
  for (int i = 0; i < 12; i++)
    for (int j = 0; j < 5; j++) {
      if (CMap[i][j] == 'A') {
        vectors[i][j].power =
            10;  // power应该指棋子的权力大小（或者说军衔大小）
        vectors[i][j].belongTo = 0;  // 0表示己方，1表示对方
      } else if (CMap[i][j] == 'B') {
        vectors[i][j].power = 9;
        vectors[i][j].belongTo = 0;
      } else if (CMap[i][j] == 'C') {
        vectors[i][j].power = 8;
        vectors[i][j].belongTo = 0;
      } else if (CMap[i][j] == 'D') {
        vectors[i][j].power = 7;
        vectors[i][j].belongTo = 0;
      } else if (CMap[i][j] == 'E') {
        vectors[i][j].power = 6;
        vectors[i][j].belongTo = 0;
      } else if (CMap[i][j] == 'F') {
        vectors[i][j].power = 5;
        vectors[i][j].belongTo = 0;
      } else if (CMap[i][j] == 'G') {
        vectors[i][j].power = 4;
        vectors[i][j].belongTo = 0;
      } else if (CMap[i][j] == 'H') {
        vectors[i][j].power = 3;
        vectors[i][j].belongTo = 0;
      } else if (CMap[i][j] == 'I') {
        vectors[i][j].power = 2;
        vectors[i][j].belongTo = 0;
      } else if (CMap[i][j] == 'J') {
        vectors[i][j].power = 12;
        vectors[i][j].belongTo = 0;
      } else if (CMap[i][j] == 'K') {
        vectors[i][j].power = 11;
        vectors[i][j].belongTo = 0;
      } else if (CMap[i][j] == 'L') {
        vectors[i][j].power = 1;
        vectors[i][j].belongTo = 0;
      } else if (CMap[i][j] == 'a') {
        vectors[i][j].power = 22;
        vectors[i][j].belongTo = 1;
      } else if (CMap[i][j] == 'b') {
        vectors[i][j].power = 21;
        vectors[i][j].belongTo = 1;
      } else if (CMap[i][j] == 'c') {
        vectors[i][j].power = 20;
        vectors[i][j].belongTo = 1;
      } else if (CMap[i][j] == 'd') {
        vectors[i][j].power = 19;
        vectors[i][j].belongTo = 1;
      } else if (CMap[i][j] == 'e') {
        vectors[i][j].power = 18;
        vectors[i][j].belongTo = 1;
      } else if (CMap[i][j] == 'f') {
        vectors[i][j].power = 17;
        vectors[i][j].belongTo = 1;
      } else if (CMap[i][j] == 'g') {
        vectors[i][j].power = 16;
        vectors[i][j].belongTo = 1;
      } else if (CMap[i][j] == 'h') {
        vectors[i][j].power = 15;
        vectors[i][j].belongTo = 1;
      } else if (CMap[i][j] == 'i') {
        vectors[i][j].power = 14;
        vectors[i][j].belongTo = 1;
      } else if (CMap[i][j] == 'j') {
        vectors[i][j].power = 24;
        vectors[i][j].belongTo = 1;
      } else if (CMap[i][j] == 'k') {
        vectors[i][j].power = 23;
        vectors[i][j].belongTo = 1;
      } else if (CMap[i][j] == 'l') {
        vectors[i][j].power = 13;
        vectors[i][j].belongTo = 1;
      } else if (CMap[i][j] == '0') {
        vectors[i][j].power = 0;     //空旗位对应的Power为0
        vectors[i][j].belongTo = 2;  //不属于哪一方，用2表示
      }
    }
}

void Board::transformcMap(char cMap[12][5], char (*CMap)[5], Chance C[25],
                          Probability pb) {
  for (int i = 0; i < 12; i++)
    for (int j = 0; j < 5; j++) {
      if (cMap[i][j] >= 'a' && cMap[i][j] <= 'l')  //将我方棋子转换为大写字母
        CMap[i][j] = cMap[i][j] - 32;
      else if (cMap[i][j] == '0')
        CMap[i][j] = cMap[i][j];  //将空位置0复制给CMap
    }
  pb.FreshAssume(pb.C, CMap);
}